﻿
using System;
using System.Collections.Generic;
using System.Data;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;

namespace Anno
{
    /// <summary>
    /// XML工具类
    /// </summary>
    public static class XmlUtil
    {
        #region GetActionDesc
        /// <summary>
        /// 从XML读取注释
        /// </summary>
        /// <returns></returns>
        public static Dictionary<string, string> GetActionDesc()
        {
            Dictionary<string, string> result = new Dictionary<string, string>();

            string xmlPath = string.Format("{0}/{1}.XML", System.AppDomain.CurrentDomain.BaseDirectory, typeof(XmlUtil).Assembly.GetName().Name);
            if (File.Exists(xmlPath))
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(xmlPath);

                XmlNode summaryNode; string type; string desc; int pos; string key;
                foreach (XmlNode node in xmlDoc.SelectNodes("//member"))
                {
                    type = type = node.Attributes["name"].Value;
                    if (type.StartsWith("M:PrisonWebApi.Controllers"))
                    {
                        pos = type.IndexOf("(");
                        if (pos == -1) pos = type.Length;
                        key = type.Substring(2, pos - 2);
                        summaryNode = node.SelectSingleNode("summary");
                        desc = summaryNode.InnerText.Trim();
                        result.Add(key, desc);
                    }
                }
            }

            return result;
        }
        #endregion
        #region XmlSerialize/DESerializer
        /// <summary>
        /// 将实体对象转换成XML
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="obj">实体对象</param>
        public static string XmlSerialize<T>(this T obj)
        {
            try
            {
                using (StringWriter sw = new StringWriter())
                {
                    Type t = obj.GetType();
                    var serializer = new XmlSerializer(obj.GetType());
                    serializer.Serialize(sw, obj);
                    sw.Close();
                    return sw.ToString();
                }
            }
            catch (Exception ex)
            {
                throw new Exception("将实体对象转换成XML异常", ex);
            }
        }

        /// <summary>
        /// 将XML转换成实体对象
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="strXML">XML</param>
        public static T DESerializer<T>(this string strXML) where T : class
        {
            try
            {
                using (var sr = new StringReader(strXML))
                {
                    var serializer = new XmlSerializer(typeof(T));
                    return serializer.Deserialize(sr) as T;
                }
            }
            catch (Exception ex)
            {
                throw new Exception("将XML转换成实体对象异常", ex);
            }
        }
        #endregion
        #region ConvertXMLToDataSet/ConvertDataSetToXML
        /// <summary>
        /// 将xml对象内容字符串转换为DataSet
        /// </summary>
        /// <param name="xmlData"></param>
        /// <returns></returns>
        public static DataSet ConvertXMLToDataSet(this string xmlData)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(xmlData);
                var xmlDS = new DataSet();
                using (var stream = new StringReader(xmlData))
                //从stream装载到XmlTextReader
                using (var reader = new XmlTextReader(stream))
                {
                    xmlDS.ReadXml(reader);
                }
                return xmlDS;
            }
            catch (System.Exception exs)
            {
                try
                {
                    if (xmlData.Length > 0)
                        return ConvertXMLToDataSet(xmlData.Substring(1));
                    throw exs;
                }
                catch (System.Exception ex)
                {
                    throw ex;
                }
            }
        }

        /// <summary>
        /// 将xml文件转换为DataSet
        /// </summary>
        /// <param name="xmlFile"></param>
        /// <returns></returns>
        public static DataSet ConvertXMLFileToDataSet(this string xmlFile)
        {
            try
            {
                var xmld = new XmlDocument();
                xmld.Load(xmlFile);

                return ConvertXMLToDataSet(xmld.InnerXml);
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 将DataSet转换为xml对象字符串
        /// </summary>
        /// <param name="xmlDS"></param>
        /// <returns></returns>
        public static string ConvertDataSetToXML(this DataSet xmlDS)
        {
            try
            {
                using (var stream = new MemoryStream())
                //从stream装载到XmlTextReader
                using (var writer = new XmlTextWriter(stream, Encoding.Unicode))
                {
                    //用WriteXml方法写入文件.
                    xmlDS.WriteXml(writer);
                    int count = (int)stream.Length;
                    byte[] arr = new byte[count];
                    stream.Seek(0, SeekOrigin.Begin);
                    stream.Read(arr, 0, count);

                    var utf = new UnicodeEncoding();
                    return utf.GetString(arr).Trim();
                }
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 将DataSet转换为xml文件
        /// </summary>
        /// <param name="xmlDS"></param>
        /// <param name="xmlFile"></param>
        public static void ConvertDataSetToXMLFile(this DataSet xmlDS, string xmlFile)
        {
            try
            {
                using (var stream = new MemoryStream())
                //从stream装载到XmlTextReader
                using (var writer = new XmlTextWriter(stream, Encoding.Unicode))
                {
                    //用WriteXml方法写入文件.
                    xmlDS.WriteXml(writer);
                    int count = (int)stream.Length;
                    byte[] arr = new byte[count];
                    stream.Seek(0, SeekOrigin.Begin);
                    stream.Read(arr, 0, count);

                    //返回Unicode编码的文本
                    var utf = new UnicodeEncoding();
                    var sw = new StreamWriter(xmlFile);
                    sw.WriteLine("<?xml version=\"1.0\\ encoding=\"utf - 8\"?>");
                    sw.WriteLine(utf.GetString(arr).Trim());
                }
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
        }
        //======================================================================================================
        /// <summary>
        /// 将Xml字符串转换成DataTable对象
        /// </summary>
        /// <param name="xmlStr">Xml字符串</param>
        /// <param name="tableIndex">Table表索引</param>
        /// <returns>DataTable对象</returns>
        public static DataTable ConvertToDataTableByXmlStringIndex(this string xmlStr, int Index)
        {
            return ConvertToDateSetByXmlString(xmlStr).Tables[Index];
        }
        /// <summary>
        /// 将Xml字符串转换成DataTable对象 第一个Table
        /// </summary>
        /// <param name="xmlStr">Xml字符串</param>
        /// <returns>DataTable对象</returns>
        public static DataTable ConvertToDataTableByXmlString(this string xmlStr)
        {
            return ConvertToDateSetByXmlString(xmlStr).Tables[0];
        }

        /// <summary>
        /// 将XML字符串转换成DATASET
        /// </summary>
        /// <param name="xmlStr"></param>
        /// <returns></returns>
        public static DataSet ConvertToDateSetByXmlString(this string xmlStr)
        {
            if (xmlStr.Length > 0)
            {
                StringReader StrStream = null;
                XmlTextReader Xmlrdr = null;
                try
                {
                    DataSet ds = new DataSet();
                    //读取字符串中的信息
                    StrStream = new StringReader(xmlStr);
                    //获取StrStream中的数据
                    Xmlrdr = new XmlTextReader(StrStream);
                    //ds获取Xmlrdr中的数据  
                    //ds.ReadXmlSchema(Xmlrdr);
                    ds.ReadXml(Xmlrdr);
                    return ds;
                }
                catch (Exception e)
                {
                    try
                    {
                        if (xmlStr?.Length > 0)
                            return ConvertToDateSetByXmlString(xmlStr.Substring(1));

                        throw e;
                    }
                    catch (Exception ee)
                    {

                        throw ee;
                    }
                }
                finally
                {
                    //释放资源
                    if (Xmlrdr != null)
                    {
                        Xmlrdr.Close();
                        StrStream.Close();
                    }
                }
            }
            else
            {
                return null;
            }
        }
        //---------------------------------------------------------------------------------
        /// <summary>
        /// 将DATASET转换成XML字符串
        /// </summary>
        /// <param name="ds"></param>
        /// <returns></returns>
        public static string ConvertToXmlStringByDataSet(this DataSet ds)
        {
            return ConvertToXmlStringByDataSetIndex(ds, -1);
        }

        ///<summary>
        /// 将DataSet对象中指定的Table转换成XML字符串 当为-1时为第一个
        /// </summary>
        /// <param name="ds">DataSet对象</param>
        /// <param name="tableIndex">DataSet对象中的Table索引</param>
        /// <returns>XML字符串</returns>
        public static string ConvertToXmlStringByDataSetIndex(this DataSet ds, int Index)
        {
            if (ds == null || ds.Tables.Count == 0) return "";
            if (Index != -1 && Index < ds.Tables.Count)
            {
                return ConvertToXmlStringByDataTable(ds.Tables[Index]);
            }
            else
            {
                return ConvertToXmlStringByDataTable(ds.Tables[0]);
            }
        }

        /// <summary>
        /// 将DATATABLE转换成XML字符串
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string ConvertToXmlStringByDataTable(this DataTable dt)
        {
            if (dt != null)
            {
                MemoryStream ms = null;
                XmlTextWriter XmlWt = null;
                try
                {
                    ms = new MemoryStream();
                    //根据ms实例化XmlWt
                    XmlWt = new XmlTextWriter(ms, Encoding.Unicode);
                    //获取ds中的数据
                    dt.WriteXml(XmlWt);
                    int count = (int)ms.Length;
                    byte[] temp = new byte[count];
                    ms.Seek(0, SeekOrigin.Begin);
                    ms.Read(temp, 0, count);
                    //返回Unicode编码的文本
                    UnicodeEncoding ucode = new UnicodeEncoding();
                    string returnValue = ucode.GetString(temp).Trim();
                    return returnValue;
                }
                catch (System.Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    //释放资源
                    if (XmlWt != null)
                    {
                        XmlWt.Close();
                        ms.Close();
                        ms.Dispose();
                    }
                }
            }
            else
            {
                return "";
            }
        }

        #endregion
        #region DataSetToList/DataRowToT
        /// <summary>        
        /// DataSetToList        
        /// </summary>         
        /// <typeparam name="T">转换类型</typeparam>        
        /// <param name="dataSet">数据源</param>        
        /// <param name="tableIndex">需要转换表的索引</param>       
        /// /// <returns>泛型集合</returns>
        public static List<T> DataSetToList<T>(this DataSet dataset, int tableIndex) where T : class, new()
        {
            //确认参数有效
            if (dataset == null || dataset.Tables.Count <= 0 || tableIndex < 0
                || tableIndex >= dataset.Tables.Count)
            {
                return null;
            }
            var dt = dataset.Tables[tableIndex];
            return ConvertToList<T>(dt);
        }
        /// <summary>        
        /// DataSetToList        
        /// </summary>         
        /// <typeparam name="T">转换类型</typeparam>        
        /// <param name="dataSet">数据源</param>        
        /// <param name="tableIndex">需要转换表的索引</param>       
        /// /// <returns>泛型集合</returns>
        public static List<T> DataSetToList<T>(this DataSet dataset, string tableName) where T : class, new()
        {
            //确认参数有效
            if (dataset == null || dataset.Tables.Count <= 0 || string.IsNullOrEmpty(tableName)
                || !dataset.Tables.Contains(tableName))
            {
                return null;
            }
            var dt = dataset.Tables[tableName];
            return ConvertToList<T>(dt);
        }
        /// <summary>
        /// DataTable到List<T>的转换
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static List<T> ConvertToList<T>(this DataTable source) where T : class, new()
        {
            return source.DataTable2List<T>();
            //List<T> itemlist = null;
            //if (source == null || source.Rows.Count == 0)
            //{
            //    return itemlist;
            //}
            //itemlist = new List<T>();
            //T item = null;
            //foreach (DataRow dr in source.Rows)
            //{
            //    item = DataRowToT<T>(dr);
            //    if (item != null)
            //        itemlist.Add(item);
            //}

            //return itemlist;
        }
        /// <summary>
        /// DataRow到T的转换
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static T DataRowToT<T>(this DataRow source) where T : class, new()
        {
            return source.DataRow2Entity<T>();
            //T item = null;
            //if (source == null)
            //{
            //    return item;
            //}
            //item = new T();
            //Type targettype = typeof(T);
            //Type ptype = null;
            //Object value = null;

            //foreach (var pi in targettype.GetProperties())
            //{
            //    if (pi.CanWrite && source.Table.Columns.Contains(pi.Name))
            //    {
            //        try
            //        {
            //            ptype = Type.GetType(pi.PropertyType.FullName);
            //            value = Convert.ChangeType(source[pi.Name], ptype);
            //            pi.SetValue(item, value, null);
            //        }
            //        catch { }
            //    }
            //}
            //return item;
        }
        #endregion
        //-------------------------------------------------------------------------------------------
        #region Table2XmlData/Table2XmlDoc/Table2DicList/XmlNodes2Dic
        /// <summary>
        /// 根据表格 生成xml串
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="mark_table">表标签</param>
        /// <param name="mark_row">行标签</param>
        /// <param name="columnName">指定列；不为空，则只生成该列的数据</param>
        /// <returns></returns>
        public static string Table2XmlData(this DataTable dt, string mark_table, string mark_row = null, string columnName = null)
        {
            StringBuilder strXml = new StringBuilder();

            if (!string.IsNullOrEmpty(mark_table))//表标签
                strXml.AppendLine("<" + mark_table + ">");
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (!string.IsNullOrEmpty(mark_row))//行标签
                    strXml.AppendLine("<" + mark_row + ">");

                if (!string.IsNullOrEmpty(columnName) && dt.Columns.Contains(columnName))//指定列标签
                {
                    if (Convert.ToString(dt.Rows[i][columnName]) != "")
                        strXml.AppendLine("<" + columnName + ">" + dt.Rows[i][columnName] + "</" + columnName + ">");
                }
                else
                {
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        if (Convert.ToString(dt.Rows[i][j]) != "")
                            strXml.AppendLine("<" + dt.Columns[j].ColumnName + ">" + dt.Rows[i][j] + "</" + dt.Columns[j].ColumnName + ">");
                    }
                }
                if (!string.IsNullOrEmpty(mark_row))
                    strXml.AppendLine("</" + mark_row + ">");
            }
            if (!string.IsNullOrEmpty(mark_table))
                strXml.AppendLine("</" + mark_table + ">");

            return strXml.ToString();
        }
        /// <summary>
        /// 根据表格 生成XmlDocument
        /// </summary>
        public static XmlDocument Table2XmlDoc(this DataTable _dt, XmlDocument xmlDoc, string xpath, string xmlNodeName)
        {
            if (_dt != null && _dt.Rows.Count > 0 && xmlDoc != null)
            {
                var xmlNode = xmlDoc.SelectSingleNode(xpath);
                if (xmlNode != null)
                {
                    foreach (DataRow _dr in _dt.Rows)
                    {
                        xmlNode.AppendChild(_dr.DataRow2XmlNode(xmlDoc, xmlNodeName));
                    }
                }
            }
            return xmlDoc;
        }
        public static XmlNode DataRow2XmlNode(this DataRow _dr, XmlDocument xmlDoc, string xmlNodeName)
        {
            var _rowX = xmlDoc.CreateElement(xmlNodeName);
            if (_dr != null && _dr.Table.Columns != null)
            {
                for (int i = 0; i < _dr.Table.Columns.Count; i++)
                {
                    var item = xmlDoc.CreateElement(_dr.Table.Columns[i].ColumnName);
                    item.InnerText = _dr[i].NullToStr();
                    _rowX.AppendChild(item);
                }
            }
            return _rowX;
        }
        /// <summary>
        /// 把一行数据添加到指定节点中
        /// </summary>
        /// <param name="_dr"></param>
        /// <param name="xmlDoc"></param>
        /// <param name="xpath"></param>
        /// <returns></returns>
        public static XmlDocument DataRowUpdateXmlNode(this DataRow _dr, XmlDocument xmlDoc, string xpath)
        {
            if (_dr != null && _dr.Table.Columns != null)
            {
                var _rowNode = xmlDoc.SelectSingleNode(xpath);
                if (_rowNode != null)
                {
                    for (int i = 0; i < _dr.Table.Columns.Count; i++)
                    {
                        var item = xmlDoc.CreateElement(_dr.Table.Columns[i].ColumnName);
                        item.InnerText = _dr[i].NullToStr();
                        _rowNode.AppendChild(item);
                    }
                }
            }
            return xmlDoc;
        }
        public static Dictionary<string, string> DataRow2Dic(this DataRow _dr)
        {
            var _drdic = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

            if (_dr != null && _dr.Table.Columns != null)
            {
                for (int i = 0; i < _dr.Table.Columns.Count; i++)
                {
                    _drdic[_dr.Table.Columns[i].ColumnName] = _dr[i].NullToStr();
                }
            }
            return _drdic;
        }
        public static List<Dictionary<string, string>> Table2DicList(this DataTable _dt)
        {
            List<Dictionary<string, string>> _lsElt = new List<Dictionary<string, string>>();
            if (_dt != null && _dt.Rows.Count > 0)
            {
                foreach (DataRow _dr in _dt.Rows)
                {
                    var lst = DataRow2Dic(_dr);
                    if (lst?.Count > 0)
                        _lsElt.Add(lst);
                }
            }
            return _lsElt;
        }

        public static Dictionary<string, string> XmlNodes2Dic(this System.Xml.XmlNode[] narr)
        {
            var _conditionDic = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            if (narr != null && narr.Length > 0)
            {
                for (var i = 0; i < narr.Length; i++)
                {
                    _conditionDic[narr[i].Name] = narr[i].InnerText;
                }
            }
            return _conditionDic;
        }
        #endregion

        #region T2XML/LT2XML /XML2T/XML2LT
        public static string T2XML<T>(this T pT)
        {
            if (pT == null) return null;
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            MemoryStream stream = new MemoryStream();
            XmlTextWriter xtw = new XmlTextWriter(stream, Encoding.UTF8);
            xtw.Formatting = Formatting.Indented;
            try
            {
                serializer.Serialize(stream, pT);
            }
            catch (Exception ex)
            {
                Log.Log.Error(ex, "序列化XML失败,类型:" + typeof(T));
                return null;
            }

            stream.Position = 0;
            StringBuilder lbreturnStr = new StringBuilder();
            using (StreamReader sr = new StreamReader(stream, Encoding.UTF8))
            {
                string line = "";
                while ((line = sr.ReadLine()) != null)
                {
                    lbreturnStr.Append(line);
                }
            }
            return lbreturnStr.ToString();
        }
        /// <summary>
        /// 对象到XML-----泛类型
        /// </summary>
        /// <typeparam name="T">泛型对象</typeparam>
        /// <param name="pLT">泛型集合</param>
        /// <returns>XML</returns>
        public static string LT2XML<T>(this List<T> pLT)
        {
            if (pLT == null) return null;
            XmlSerializer serializer = new XmlSerializer(typeof(List<T>));
            MemoryStream stream = new MemoryStream();
            XmlTextWriter xtw = new XmlTextWriter(stream, Encoding.UTF8);
            xtw.Formatting = Formatting.Indented;
            try
            {
                serializer.Serialize(stream, pLT);
            }
            catch (Exception ex)
            {
                Log.Log.Error(ex, "序列化XML失败,类型:" + typeof(T));
                return null;
            }

            stream.Position = 0;
            StringBuilder lbreturnStr = new StringBuilder();
            using (StreamReader sr = new StreamReader(stream, Encoding.UTF8))
            {
                string line = "";
                while ((line = sr.ReadLine()) != null)
                {
                    lbreturnStr.Append(line);
                }
            }
            return lbreturnStr.ToString();
        }

        /// <summary>
        /// XML到反序列化到对象----支持泛类型
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="psXML">XML数据</param>
        /// <returns>返回泛型实体</returns>
        public static T XML2T<T>(this string psXML)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                using (StreamWriter sw = new StreamWriter(stream, Encoding.UTF8))
                {
                    sw.Write(psXML);
                    sw.Flush();
                    stream.Seek(0, SeekOrigin.Begin);
                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    try
                    {
                        return ((T)serializer.Deserialize(stream));
                    }
                    catch (Exception ex)
                    { return default(T); }

                }
            }
        }

        /// <summary>
        /// XML到反序列化到对象----支持泛类型
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="psXML">XML数据</param>
        /// <returns>返回泛型实体</returns>
        public static List<T> XML2LT<T>(this string psXML)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                using (StreamWriter sw = new StreamWriter(stream, Encoding.UTF8))
                {
                    sw.Write(psXML);
                    sw.Flush();
                    stream.Seek(0, SeekOrigin.Begin);
                    XmlSerializer serializer = new XmlSerializer(typeof(List<T>));
                    try
                    {
                        return ((List<T>)serializer.Deserialize(stream));
                    }
                    catch (Exception ex)
                    { return default(List<T>); }

                }
            }
        }
        #endregion

        #region XDocument
        /// <summary>
        /// 获取某节点存在量
        /// </summary>
        /// <returns></returns>
        public static int GetXmlNodeCount(string _xmlStr, string _nodeName)
        {
            try
            {
                XDocument _xdoc = XDocument.Parse(_xmlStr);
                var _nodes = _xdoc.Descendants(_nodeName).ToList();
                if (_nodes.Count > 0)
                    return _nodes.Count;
                else
                    return 0;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// 判断是否存在指定节点
        /// </summary>
        public static bool IsExistedNode(string _xmlStr, string _nodeName)
        {
            try
            {
                return GetXmlNodeCount(_xmlStr, _nodeName) > 0;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// 获取指定节点的值
        /// </summary>
        /// <param name="_xml">xml字符串</param>
        /// <param name="_node">节点名</param>
        public static List<string> GetXmlNodeValue(string _xmlStr, string _nodeName)
        {
            try
            {
                XDocument _xdoc = XDocument.Parse(_xmlStr);
                var _nodes = _xdoc.Descendants(_nodeName).ToList();
                if (_nodes.Count > 0)
                    return _nodes.Select(s => s.Value).ToList();
                else
                    return new List<string>();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// 获取具有指定的 System.Xml.Linq.XName 的第一个（按文档顺序）子元素
        /// </summary>
        /// <param name="xmlElement">X节点</param>
        /// <param name="subElementName">要匹配xmlElementName子元素名称</param>
        /// <returns>返回子元素值</returns>
        public static string GetXElementValue(this System.Xml.Linq.XElement xmlElement, string subElementName, string defValue = "")
        {
            try
            {
                if (xmlElement != null && xmlElement.HasElements)
                {
                    var Attr = xmlElement.Element(subElementName);
                    if (Attr != null)
                    {
                        var val = Attr.Value;
                        if (!val.IsNullOrEmpty()) return val;
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return defValue;
        }
        public static List<T> XElementsToLT<T>(this IEnumerable<XElement> xElements)
        {
            // 定义集合    
            List<T> ts = new List<T>();
            foreach (var element in xElements)
            {
                var obj = element.XElementToT<T>();
                ts.Add(obj);
            }
            return ts;
        }
        /// <summary>
        /// XElement转实体对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="xmlElement">X节点</param>
        /// <returns></returns>
        public static T XElementToT<T>(this System.Xml.Linq.XElement xmlElement)
        {
            T obj = default(T);
            try
            {
                if (xmlElement != null && xmlElement.HasElements)
                {
                    obj = FastReflection.FastInstance<T>();
                    // 获得此模型的公共属性      
                    var propertys = obj.GetType().GetProperties();
                    foreach (var pi in propertys)
                    {
                        // 判断此属性是否有Setter 
                        if (!pi.CanWrite) continue;
                        object value = xmlElement.GetXElementValue(pi.Name, null);

                        if (value.IsNotNullOrEmpty_())
                        {
                            pi.FastSetValue(obj, value);
                        }
                    }
                    var fields = obj.GetType().GetFields();
                    foreach (var pi in fields)
                    {
                        object value = xmlElement.GetXElementValue(pi.Name, null);
                        if (value.IsNotNullOrEmpty_())
                        {
                            pi.FastSetValue(obj, value);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return obj;
        }
        #endregion

        #region XmlDocument 文档创建
        /// <summary>
        /// 创建一个带有根节点的Xml文件
        /// </summary>
        /// <param name="xmlData">Xml数据</param>
        ///<returns></returns>
        public static XmlDocument CreateXmlDocumentByXmlData(string xmlData)
        {
            xmlData = XmlUtil.ReplaceXmlns(xmlData);
            var xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(xmlData);
            return xmlDoc;
        }

        /// <summary>
        /// 创建一个XML文档
        /// </summary>
        /// <param name="rootNodeName">XML文档根节点名称(须指定一个根节点名称)</param>
        /// <param name="version">XML文档版本号(必须为:"1.0")</param>
        /// <param name="encoding">XML文档编码方式</param>
        /// <param name="standalone">该值必须是"yes"或"no",如果为null,Save方法不在XML声明上写出独立属性</param>
        /// <returns>成功返回true,失败返回false</returns>
        public static XmlDocument CreateXmlDocument(string rootNodeName, string version = "1.0", string encoding = "UTF-8", string standalone = "yes")
        {
            XmlDocument _xmlDocument = new XmlDocument();
            try
            {
                XmlDeclaration xmlDeclaration = _xmlDocument.CreateXmlDeclaration(version, encoding, standalone);
                XmlNode root = _xmlDocument.CreateElement(rootNodeName);
                _xmlDocument.AppendChild(xmlDeclaration);
                _xmlDocument.AppendChild(root);
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return _xmlDocument;
        }
        /// <summary>
        /// 创建一个XML文档
        /// </summary>
        /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
        /// <param name="rootNodeName">XML文档根节点名称(须指定一个根节点名称)</param>
        /// <param name="version">XML文档版本号(必须为:"1.0")</param>
        /// <param name="encoding">XML文档编码方式</param>
        /// <param name="standalone">该值必须是"yes"或"no",如果为null,Save方法不在XML声明上写出独立属性</param>
        /// <returns>成功返回true,失败返回false</returns>
        public static bool CreateXmlDocument(string xmlFileName, string rootNodeName, string version = "1.0", string encoding = "UTF-8", string standalone = "yes")
        {
            bool isSuccess = false;
            try
            {
                var xmlDoc = CreateXmlDocument(rootNodeName, version, encoding, standalone);
                xmlDoc.Save(xmlFileName);
                isSuccess = true;
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }


        /// <summary>
        /// 依据匹配XPath表达式的第一个节点来创建它的子节点(如果此节点已存在则追加一个新的同名节点
        /// </summary>
        /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <param name="xmlNodeName">要匹配xmlNodeName的节点名称</param>
        /// <param name="innerText">节点文本值</param>
        /// <param name="xmlAttributeName">要匹配xmlAttributeName的属性名称</param>
        /// <param name="value">属性值</param>
        /// <returns>成功返回true,失败返回false</returns>
        public static bool CreateXmlNodeByXPath(string xmlFileName, string xpath, string xmlNodeName, string innerText, string xmlAttributeName, string value)
        {
            bool isSuccess = false;
            XmlDocument xmlDoc = new XmlDocument();
            try
            {
                xmlDoc.Load(xmlFileName); //加载XML文档
                isSuccess = CreateXmlNodeByXPath(xmlDoc, xpath, xmlNodeName, innerText, xmlAttributeName, value);
                xmlDoc.Save(xmlFileName); //保存到XML文档
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }

        /// <summary>
        /// 依据匹配XPath表达式的第一个节点来创建它的子节点(如果此节点已存在则追加一个新的同名节点
        /// </summary>
        /// <param name="_xmlDocument">XML文档完全文件名(包含物理路径)</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <param name="xmlNodeName">要匹配xmlNodeName的节点名称</param>
        /// <param name="innerText">节点文本值</param>
        /// <param name="xmlAttributeName">要匹配xmlAttributeName的属性名称</param>
        /// <param name="value">属性值</param>
        /// <returns>成功返回true,失败返回false</returns>
        public static bool CreateXmlNodeByXPath(XmlDocument _xmlDocument, string xpath, string xmlNodeName, string innerText, string xmlAttributeName, string value)
        {
            bool isSuccess = false;
            try
            {
                XmlNode xmlNode = _xmlDocument.SelectSingleNode(xpath);
                if (xmlNode != null)
                {
                    //存不存在此节点都创建
                    XmlElement subElement = _xmlDocument.CreateElement(xmlNodeName);
                    subElement.InnerXml = innerText;

                    //如果属性和值参数都不为空则在此新节点上新增属性
                    if (!string.IsNullOrEmpty(xmlAttributeName) && !string.IsNullOrEmpty(value))
                    {
                        XmlAttribute xmlAttribute = _xmlDocument.CreateAttribute(xmlAttributeName);
                        xmlAttribute.Value = value;
                        subElement.Attributes.Append(xmlAttribute);
                    }

                    xmlNode.AppendChild(subElement);
                }
                isSuccess = true;
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }
        #endregion
        #region XmlDocument 文档节点或属性的添加、修改
        /// <summary>
        /// 依据匹配XPath表达式的第一个节点来创建或更新它的子节点(如果节点存在则更新,不存在则创建)
        /// </summary>
        /// <param name="_xmlDocument">XML文档完全文件名(包含物理路径)</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <param name="xmlNodeName">要匹配xmlNodeName的节点名称</param>
        /// <param name="innerText">节点文本值</param>
        /// <returns>成功返回true,失败返回false</returns>
        public static bool CreateOrUpdateXmlNodeByXPath(this XmlDocument _xmlDocument, string xpath, string xmlNodeName, string innerText)
        {
            bool isSuccess = false;
            bool isExistsNode = false;//标识节点是否存在
            try
            {
                var xmlNode = _xmlDocument.SelectSingleNode(xpath);
                if (xmlNode != null)
                {
                    //遍历xpath节点下的所有子节点
                    foreach (XmlNode node in xmlNode.ChildNodes)
                    {
                        if (node.Name.ToLower() == xmlNodeName.ToLower())
                        {
                            //存在此节点则更新
                            node.InnerXml = innerText;
                            isExistsNode = true;
                            break;
                        }
                    }
                    if (!isExistsNode)
                    {
                        //不存在此节点则创建
                        var subElement = _xmlDocument.CreateElement(xmlNodeName);
                        subElement.InnerXml = innerText;
                        xmlNode.AppendChild(subElement);
                    }
                }
                isSuccess = true;
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }
        /// <summary>
        /// 依据匹配XPath表达式的第一个节点来创建或更新它的子节点(如果节点存在则更新,不存在则创建)
        /// </summary>
        /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <param name="xmlNodeName">要匹配xmlNodeName的节点名称</param>
        /// <param name="innerText">节点文本值</param>
        /// <returns>成功返回true,失败返回false</returns>
        public static bool CreateOrUpdateXmlNodeByXPath(string xmlFileName, string xpath, string xmlNodeName, string innerText)
        {
            bool isSuccess = false;
            XmlDocument xmlDoc = new XmlDocument();
            try
            {
                xmlDoc.Load(xmlFileName); //加载XML文档
                isSuccess = CreateOrUpdateXmlNodeByXPath(xmlDoc, xpath, xmlNodeName, innerText);
                xmlDoc.Save(xmlFileName); //保存到XML文档
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }


        /// <summary>
        /// 依据匹配XPath表达式的第一个节点来创建或更新它的属性(如果属性存在则更新,不存在则创建)
        /// </summary>
        /// <param name="_xmlDocument">XML文档完全文件名(包含物理路径)</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <param name="xmlAttributeName">要匹配xmlAttributeName的属性名称</param>
        /// <param name="value">属性值</param>
        /// <returns>成功返回true,失败返回false</returns>
        public static bool CreateOrUpdateXmlAttributeByXPath(this XmlDocument _xmlDocument, string xpath, string xmlAttributeName, string value)
        {
            bool isSuccess = false;
            bool isExistsAttribute = false;//标识属性是否存在
            try
            {
                XmlNode xmlNode = _xmlDocument.SelectSingleNode(xpath);
                if (xmlNode != null)
                {
                    //遍历xpath节点中的所有属性
                    foreach (XmlAttribute attribute in xmlNode.Attributes)
                    {
                        if (attribute.Name.ToLower() == xmlAttributeName.ToLower())
                        {
                            //节点中存在此属性则更新
                            attribute.Value = value;
                            isExistsAttribute = true;
                            break;
                        }
                    }
                    if (!isExistsAttribute)
                    {
                        //节点中不存在此属性则创建
                        XmlAttribute xmlAttribute = _xmlDocument.CreateAttribute(xmlAttributeName);
                        xmlAttribute.Value = value;
                        xmlNode.Attributes.Append(xmlAttribute);
                    }
                }
                isSuccess = true;
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }
        /// <summary>
        /// 依据匹配XPath表达式的第一个节点来创建或更新它的属性(如果属性存在则更新,不存在则创建)
        /// </summary>
        /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <param name="xmlAttributeName">要匹配xmlAttributeName的属性名称</param>
        /// <param name="value">属性值</param>
        /// <returns>成功返回true,失败返回false</returns>
        public static bool CreateOrUpdateXmlAttributeByXPath(string xmlFileName, string xpath, string xmlAttributeName, string value)
        {
            bool isSuccess = false;
            XmlDocument xmlDoc = new XmlDocument();
            try
            {
                xmlDoc.Load(xmlFileName); //加载XML文档
                isSuccess = CreateOrUpdateXmlAttributeByXPath(xmlDoc, xpath, xmlAttributeName, value);
                xmlDoc.Save(xmlFileName); //保存到XML文档
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }

        /// <summary>
        /// 对象到XML-----泛类型
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="pT">对象</param>
        /// <returns>XML</returns>
        private static string ReplaceXmlns(string xml)
        {
            if (xml == null) return null;
            if (xml.IndexOf("xmlns=", StringComparison.OrdinalIgnoreCase) > 0)
            {
                //xml = System.Text.RegularExpressions.Regex.Replace(xml,
                //@"(xmlns[^=]*=[""][^""]*[""])", "",
                //System.Text.RegularExpressions.RegexOptions.IgnoreCase |
                //System.Text.RegularExpressions.RegexOptions.Multiline);

                xml = System.Text.RegularExpressions.Regex.Replace(xml,
                   @"(xmlns:*[^=]*=[""][^""]*[""])", "",
                   System.Text.RegularExpressions.RegexOptions.IgnoreCase |
                   System.Text.RegularExpressions.RegexOptions.Multiline);

                xml = System.Text.RegularExpressions.Regex.Replace(xml,
                  @"(xsi:*[^=]*=[""][^""]*[""])", "",
                  System.Text.RegularExpressions.RegexOptions.IgnoreCase |
                  System.Text.RegularExpressions.RegexOptions.Multiline);
            }
            return xml;
        }
        #endregion
        #region XmlDocument 文档节点查询和读取
        /// <summary>
        /// 选择匹配XPath表达式的第一个节点XmlNode.
        /// </summary>
        /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名")</param>
        /// <returns>返回XmlNode</returns>
        public static XmlNode GetXmlNodeByXpath(this XmlDocument _xmlDocument, string xpath)
        {
            try
            {
                XmlNode xmlNode = _xmlDocument.SelectSingleNode(xpath);
                return xmlNode;
            }
            catch (Exception)
            {
                return null;
                //throw ex; //这里可以定义你自己的异常处理
            }
        }
        /// <summary>
        /// 选择匹配XPath表达式的第一个节点XmlNode.
        /// </summary>
        /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名")</param>
        /// <returns>返回XmlNode</returns>
        public static XmlNode GetXmlNodeByXpath(string xmlFileName, string xpath)
        {
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(xmlFileName); //加载XML文档
                return GetXmlNodeByXpath(xmlDoc, xpath);
            }
            catch (Exception)
            {
                return null;
                //throw ex; //这里可以定义你自己的异常处理
            }
        }

        /// <summary>
        /// 选择匹配XPath表达式的节点列表XmlNodeList.
        /// </summary>
        /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名")</param>
        /// <returns>返回XmlNodeList</returns>
        public static XmlNodeList GetXmlNodeListByXpath(this XmlDocument _xmlDocument, string xpath)
        {
            try
            {
                XmlNodeList xmlNodeList = _xmlDocument.SelectNodes(xpath);
                return xmlNodeList;
            }
            catch (Exception)
            {
                return null;
                //throw ex; //这里可以定义你自己的异常处理
            }
        }
        /// <summary>
        /// 选择匹配XPath表达式的节点列表XmlNodeList.
        /// </summary>
        /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名")</param>
        /// <returns>返回XmlNodeList</returns>
        public static XmlNodeList GetXmlNodeListByXpath(string xmlFileName, string xpath)
        {
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(xmlFileName); //加载XML文档
                return GetXmlNodeListByXpath(xmlDoc, xpath);
            }
            catch (Exception)
            {
                return null;
                //throw ex; //这里可以定义你自己的异常处理
            }
        }

        /// <summary>
        /// 选择匹配XPath表达式的第一个节点的匹配xmlAttributeName的属性XmlAttribute.
        /// </summary>
        /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <param name="xmlAttributeName">要匹配xmlAttributeName的属性名称</param>
        /// <returns>返回xmlAttributeName</returns>
        public static XmlAttribute GetXmlAttribute(this XmlDocument _xmlDocument, string xpath, string xmlAttributeName)
        {
            string content = string.Empty;
            XmlAttribute xmlAttribute = null;
            try
            {
                XmlNode xmlNode = _xmlDocument.SelectSingleNode(xpath);
                if (xmlNode != null)
                {
                    if (xmlNode.Attributes.Count > 0)
                    {
                        xmlAttribute = xmlNode.Attributes[xmlAttributeName];
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return xmlAttribute;
        }
        /// <summary>
        /// 选择匹配XPath表达式的第一个节点的匹配xmlAttributeName的属性XmlAttribute.
        /// </summary>
        /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <param name="xmlAttributeName">要匹配xmlAttributeName的属性名称</param>
        /// <returns>返回xmlAttributeName</returns>
        public static XmlAttribute GetXmlAttribute(string xmlFileName, string xpath, string xmlAttributeName)
        {
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(xmlFileName); //加载XML文档
                return GetXmlAttribute(xmlDoc, xpath, xmlAttributeName);
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
        }
        #endregion
        #region XmlDocument 文档节点或属性的删除
        /// <summary>
        /// 删除匹配XPath表达式的第一个节点(节点中的子元素同时会被删除)
        /// </summary>
        /// <param name="xmlDoc">XML文档</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <returns>成功返回true,失败返回false</returns>
        public static bool DeleteXmlNodeByXPath(this XmlDocument xmlDoc, string xpath)
        {
            bool isSuccess = false;
            try
            {
                if (xmlDoc == null) return isSuccess;
                XmlNode xmlNode = xmlDoc.SelectSingleNode(xpath);
                if (xmlNode != null)
                {
                    //删除节点
                    xmlNode.ParentNode.RemoveChild(xmlNode);
                }
                isSuccess = true;
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }
        /// <summary>
        /// 删除匹配XPath表达式的第一个节点(节点中的子元素同时会被删除)
        /// </summary>
        /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <returns>成功返回true,失败返回false</returns>
        public static bool DeleteXmlNodeByXPath(string xmlFileName, string xpath)
        {
            bool isSuccess = false;
            XmlDocument xmlDoc = new XmlDocument();
            try
            {
                xmlDoc.Load(xmlFileName); //加载XML文档
                isSuccess = DeleteXmlNodeByXPath(xmlDoc, xpath);
                xmlDoc.Save(xmlFileName); //保存到XML文档
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }

        /// <summary>
        /// 删除匹配XPath表达式的第一个节点中的匹配参数xmlAttributeName的属性
        /// </summary>
        /// <param name="xmlDoc">XML文档</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <param name="xmlAttributeName">要删除的xmlAttributeName的属性名称</param>
        /// <returns>成功返回true,失败返回false</returns>
        public static bool DeleteXmlAttributeByXPath(this XmlDocument xmlDoc, string xpath, string xmlAttributeName)
        {
            bool isSuccess = false;
            bool isExistsAttribute = false;
            try
            {
                if (xmlDoc == null) return isSuccess;
                XmlNode xmlNode = xmlDoc.SelectSingleNode(xpath);
                XmlAttribute xmlAttribute = null;
                if (xmlNode != null)
                {
                    //遍历xpath节点中的所有属性
                    foreach (XmlAttribute attribute in xmlNode.Attributes)
                    {
                        if (attribute.Name.ToLower() == xmlAttributeName.ToLower())
                        {
                            //节点中存在此属性
                            xmlAttribute = attribute;
                            isExistsAttribute = true;
                            break;
                        }
                    }
                    if (isExistsAttribute)
                    {
                        //删除节点中的属性
                        xmlNode.Attributes.Remove(xmlAttribute);
                    }
                }
                isSuccess = true;
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }
        /// <summary>
        /// 删除匹配XPath表达式的第一个节点中的匹配参数xmlAttributeName的属性
        /// </summary>
        /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <param name="xmlAttributeName">要删除的xmlAttributeName的属性名称</param>
        /// <returns>成功返回true,失败返回false</returns>
        public static bool DeleteXmlAttributeByXPath(string xmlFileName, string xpath, string xmlAttributeName)
        {
            bool isSuccess = false;
            XmlDocument xmlDoc = new XmlDocument();
            try
            {
                xmlDoc.Load(xmlFileName); //加载XML文档
                isSuccess = DeleteXmlAttributeByXPath(xmlDoc, xpath, xmlAttributeName);
                xmlDoc.Save(xmlFileName); //保存到XML文档
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }

        /// <summary>
        /// 删除匹配XPath表达式的第一个节点中的所有属性
        /// </summary>
        /// <param name="xmlDoc">XML文档</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <returns>成功返回true,失败返回false</returns>
        public static bool DeleteAllXmlAttributeByXPath(this XmlDocument xmlDoc, string xpath)
        {
            bool isSuccess = false;
            try
            {
                if (xmlDoc == null) return isSuccess;
                XmlNode xmlNode = xmlDoc.SelectSingleNode(xpath);
                if (xmlNode != null)
                {
                    //遍历xpath节点中的所有属性
                    xmlNode.Attributes.RemoveAll();
                }
                isSuccess = true;
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }
        /// <summary>
        /// 删除匹配XPath表达式的第一个节点中的所有属性
        /// </summary>
        /// <param name="xmlFileName">XML文档完全文件名(包含物理路径)</param>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <returns>成功返回true,失败返回false</returns>
        public static bool DeleteAllXmlAttributeByXPath(string xmlFileName, string xpath)
        {
            bool isSuccess = false;
            XmlDocument xmlDoc = new XmlDocument();
            try
            {
                xmlDoc.Load(xmlFileName); //加载XML文档
                isSuccess = DeleteAllXmlAttributeByXPath(xmlDoc, xpath);
                xmlDoc.Save(xmlFileName); //保存到XML文档
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }
        #endregion

        #region Table2Dynamic/DataRow2Dynamic/DicToDynamic
      
        public static dynamic DicToDynamic(this IDictionary<string, object> dict)
        {
            if (dict == null || dict.Count == 0) return null;
            dynamic result = new System.Dynamic.ExpandoObject();
            foreach (var entry in dict)
            {
                (result as ICollection<KeyValuePair<string, object>>).Add(new KeyValuePair<string, object>(entry.Key, entry.Value));
            }
            return result;
        }
        public static dynamic DataRow2Dynamic(this DataRow _dr)
        {
            dynamic result = null;
            if (_dr != null && _dr.Table.Columns != null && _dr.Table.Columns.Count > 0)
            {
                result = new DynamicSerializable();// System.Dynamic.ExpandoObject();
                for (int i = 0; i < _dr.Table.Columns.Count; i++)
                {
                    // (result as ICollection<KeyValuePair<string, object>>).Add(new KeyValuePair<string, object>(_dr.Table.Columns[i].ColumnName, _dr[i].NullToStr()));
                    result.Add(_dr.Table.Columns[i].ColumnName, _dr[i].NullToStr());
                }
            }
            return result;
        }
        public static List<dynamic> Table2Dynamic(this DataTable _dt)
        {
            List<dynamic> _lsElt = new List<dynamic>();
            if (_dt != null && _dt.Rows.Count > 0)
            {
                foreach (DataRow _dr in _dt.Rows)
                {
                    var lst = _dr.DataRow2Dynamic();
                    if (lst != null)
                        _lsElt.Add(lst);
                }
            }
            return _lsElt;
        }
        public static Dictionary<string, string> XmlNodes2Dic(this System.Xml.XmlElement[] narr)
        {
            var _conditionDic = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            if (narr != null && narr.Length > 0)
            {
                for (var i = 0; i < narr.Length; i++)
                {
                    _conditionDic[narr[i].Name] = narr[i].InnerText;
                }
            }
            return _conditionDic;
        }
        public static Dictionary<string, string> XmlNodes2Dic(this XElement[] narr)
        {
            var _conditionDic = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            if (narr != null && narr.Length > 0)
            {
                for (var i = 0; i < narr.Length; i++)
                {
                    _conditionDic[narr[i].Name.LocalName] = narr[i].Value;
                }
            }
            return _conditionDic;
        }
        #endregion
    }

    [Serializable]
    public class DynamicSerializable : DynamicObject, System.Runtime.Serialization.ISerializable
    {
        private readonly Dictionary<string, object> dictionary = new Dictionary<string, object>();

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            dictionary[binder.Name] = value;

            return true;
        }
        public void Add(string binderName, object val)
        {
            dictionary[binderName] = val;
        }

        public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
        {
            foreach (var kvp in dictionary)
            {
                info.AddValue(kvp.Key, kvp.Value);
            }
        }
    }

    #region SingleXmlHelp
    ///////////////////////////////////////////////
    //Demo:
    //Xml.Help.SingleXmlHelp singleXml = new Xml.Help.SingleXmlHelp("config.xml", "configuration", "utf-8");
    ////添加带熟悉的rules
    //var attribute = new Hashtable();
    //attribute.Add("name", "changeUrl");
    //attribute.Add("stopProcessing", "true");
    //singleXml.InsertNode("rules", true, "configuration//system.webServer//rewrite", attribute, null);
    //
    //var update = new Hashtable();
    //update.Add("stopProcessing", "false");
    ////更新rules属性值
    //singleXml.UpdateNode("configuration//system.webServer//rewrite", update, new Hashtable());
    //
    ////删除节点的属性
    //singleXml.DeleteXmlAttributeByXPath("configuration//system.webServer//rewrite//rules", "name");
    //
    ///////////////////////////////////////////////


    public class SingleXmlHelp
    {
        /// <summary>
        /// xml文件信息
        /// </summary>
        public XmlDocument xmlDoc { get; private set; }

        /// <summary>
        /// xml文件地址
        /// </summary>
        public string fileName { get; private set; }

        /// <summary>
        /// 加载xml数据（若文件不存在，则自动建立一个xml文件）
        /// </summary>
        /// <param name="fileName">xml文件地址</param>
        /// <param name="rootName">根结点名称</param>
        /// <param name="encoding">编码</param>
        public SingleXmlHelp(string fileName, string rootName, string encoding = "utf-8")
        {
            if (string.IsNullOrWhiteSpace(fileName))
                throw new ArgumentOutOfRangeException("fileName");

            if (!File.Exists(fileName))
            {
                CreatexmlDocument(fileName, rootName, encoding);
            }
            else
            {
                xmlDoc = new XmlDocument();
                xmlDoc.Load(fileName);
            }

            if (!XmlHasFile())
                throw new NullReferenceException("Xml数据信息为空！");

            this.fileName = fileName;
        }
        /// <summary>
        /// 加载xml数据
        /// </summary>
        /// <param name="fileName">xml文件地址</param>
        /// <param name="rootName">根结点名称</param>
        /// <param name="encoding">编码</param>
        public SingleXmlHelp(string xmlData)
        {
            if (string.IsNullOrWhiteSpace(xmlData))
                throw new ArgumentOutOfRangeException("xmlData");

            CreatexmlDocument(xmlData);

            if (!XmlHasFile())
                throw new NullReferenceException("Xml数据信息为空！");
        }
        /// <summary>
        /// 对象到XML-----泛类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="pT"></param>
        /// <returns></returns>
        public static SingleXmlHelp CreateSingleXmlHelp<T>(T pT)
        {
            if (pT == null)
                throw new ArgumentOutOfRangeException("pT");
            var xmlData = T2XML(pT);
            if (string.IsNullOrWhiteSpace(xmlData))
                throw new ArgumentOutOfRangeException("xmlData");

            return new SingleXmlHelp(xmlData);
        }
        /// <summary>
        /// 对象到XML-----泛类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="pLT"></param>
        /// <returns></returns>
        public static SingleXmlHelp CreateSingleXmlHelp<T>(List<T> pLT)
        {
            if (pLT == null || pLT.Count == 0)
                throw new ArgumentOutOfRangeException("pLT");
            var xmlData = T2XML(pLT);
            if (string.IsNullOrWhiteSpace(xmlData))
                throw new ArgumentOutOfRangeException("xmlData");

            return new SingleXmlHelp(xmlData);
        }
        /// <summary>
        /// XML到反序列化到对象----支持泛类型
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <returns>返回泛型实体</returns>
        public T XML2T<T>()
        {
            if (this.xmlDoc == null)
                throw new ArgumentOutOfRangeException("xmlDoc");
            string psXML = this.xmlDoc.OuterXml;
            if (string.IsNullOrWhiteSpace(psXML))
                throw new ArgumentOutOfRangeException("xmlDoc.OuterXml");
            return XML2T<T>(psXML);
        }
        /// <summary>
        /// XML到反序列化到对象----支持泛类型
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <returns>返回泛型实体</returns>
        public List<T> XML2LT<T>()
        {
            if (this.xmlDoc == null)
                throw new ArgumentOutOfRangeException("xmlDoc");
            string psXML = this.xmlDoc.OuterXml;
            if (string.IsNullOrWhiteSpace(psXML))
                throw new ArgumentOutOfRangeException("xmlDoc.OuterXml");
            return XML2LT<T>(psXML);
        }

        #region 公共方法
        /// <summary>
        /// 重新加载新的Xml文件
        /// </summary>
        /// <param name="fileName">xml文件地址</param>
        public void ReLoadFile(string fileName)
        {
            this.xmlDoc = new XmlDocument();
            this.xmlDoc.Load(fileName);
            this.fileName = fileName;
        }

        /// <summary>
        /// 释放xml文件
        /// </summary>
        /// <param name="save">释放前是否保持文件信息</param>
        public void Dispose(bool save = false)
        {
            if (save && !string.IsNullOrWhiteSpace(fileName))
                xmlDoc.Save(fileName);
            xmlDoc = null;
            fileName = string.Empty;
        }
        /// <summary>
        /// 保存到XML文档
        /// </summary>
        /// <returns></returns>
        public bool SaveXmlDoc()
        {
            if (xmlDoc != null && !string.IsNullOrWhiteSpace(fileName))
            {
                xmlDoc.Save(fileName);
                return true;
            }
            return false;
        }
        #endregion

        #region 增删改
        /// <summary>
        /// 插入一个节点和它的若干子节点
        /// </summary>
        /// <param name="NewNodeName">插入的节点名称</param>
        /// <param name="HasAttributes">此节点是否具有属性，True为有，False为无</param>
        /// <param name="fatherNode">此插入节点的父节点,要匹配的XPath表达式(例如:"//节点名//子节点名)</param>
        /// <param name="htAtt">此节点的属性，Key为属性名，Value为属性值</param>
        /// <param name="htSubNode">子节点的属性，Key为Name,Value为InnerText</param>
        /// <returns>返回真为更新成功，否则失败</returns>
        public XmlElement InsertNode(string NewNodeName, bool HasAttributes, string fatherNode, IDictionary<string, object> htAtt, IDictionary<string, object> htSubNode = null, bool isSaveXmlDoc = true)
        {
            try
            {
                XmlNode root = SelectSingleNode(fatherNode, !fatherNode.Contains("["));// xmlDoc.SelectSingleNode(fatherNode);
                if (root == null)
                {
                    root = xmlDoc.CreateElement(fatherNode);
                }
                return InsertNode(NewNodeName, HasAttributes, root, htAtt, htSubNode, isSaveXmlDoc);
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }
        /// <summary>
        /// 插入一个节点和它的若干子节点
        /// </summary>
        /// <param name="NewNodeName">插入的节点名称</param>
        /// <param name="HasAttributes">此节点是否具有属性，True为有，False为无</param>
        /// <param name="fatherNode">此插入节点的父节点,要匹配的XPath表达式(例如:"//节点名//子节点名)</param>
        /// <param name="htAtt">此节点的属性，Key为属性名，Value为属性值</param>
        /// <param name="htSubNode">子节点的属性，Key为Name,Value为InnerText</param>
        /// <returns>返回真为更新成功，否则失败</returns>
        public XmlElement InsertNode(string NewNodeName, bool HasAttributes, XmlNode fatherNode, IDictionary<string, object> htAtt, IDictionary<string, object> htSubNode = null, bool isSaveXmlDoc = true)
        {
            try
            {
                if (!XmlHasFile())
                    throw new NullReferenceException("Xml Files Is Null");

                if (fatherNode == null)
                {
                    throw new NullReferenceException("Father Node Is Null");
                }
                var xmlelem = xmlDoc.CreateElement(NewNodeName);
                if (htAtt != null && HasAttributes)//若此节点有属性，则先添加属性
                {
                    SetAttributes(xmlelem, htAtt);
                    SetNodes(xmlelem.Name, xmlDoc, xmlelem, htSubNode);//添加完此节点属性后，再添加它的子节点和它们的InnerText
                }
                else
                {
                    SetNodes(xmlelem.Name, xmlDoc, xmlelem, htSubNode);//若此节点无属性，那么直接添加它的子节点
                }
                fatherNode.AppendChild(xmlelem);
                if (isSaveXmlDoc)
                    SaveXmlDoc();
                return xmlelem;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }

        /// <summary>
        /// 更新节点
        /// </summary>
        /// <param name="fatherNode">需要更新节点的上级节点,要匹配的XPath表达式(例如:"//节点名//子节点名)</param>
        /// <param name="htAtt">需要更新的属性表，Key代表需要更新的属性，Value代表更新后的值</param>
        /// <param name="htSubNode">需要更新的子节点的属性表，Key代表需要更新的子节点名字Name,Value代表更新后的值InnerText</param>
        /// <returns>返回真为更新成功，否则失败</returns>
        public bool UpdateNode(string fatherNode, IDictionary<string, object> htAtt, IDictionary<string, object> htSubNode, bool isSaveXmlDoc = true)
        {
            try
            {
                if (!XmlHasFile())
                    throw new NullReferenceException("Xml Files Is Null");
                var xmlnode = xmlDoc.SelectSingleNode(fatherNode);
                if (xmlnode != null)
                {
                    var root = xmlnode.ChildNodes;
                    UpdateNodes(root, htAtt, htSubNode);
                    if (isSaveXmlDoc)
                        SaveXmlDoc();
                    return true;
                }
                return false;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }

        /// <summary>
        /// 删除指定节点下的子节点
        /// </summary>
        /// <param name="fatherNode">制定节点,要匹配的XPath表达式(例如:"//节点名//子节点名)</param>
        /// <returns>返回真为更新成功，否则失败</returns>
        public bool DeleteNodes(string fatherNode, bool isSaveXmlDoc = true)
        {
            try
            {
                if (!XmlHasFile())
                    throw new NullReferenceException("Xml Files Is Null");

                var xmlnode = xmlDoc.SelectSingleNode(fatherNode);
                if (xmlnode != null)
                {
                    xmlnode.RemoveAll();
                    if (isSaveXmlDoc)
                        SaveXmlDoc();
                    return true;
                }
                return false;
            }
            catch (XmlException xe)
            {
                throw new XmlException(xe.Message);
            }
        }
        /// <summary>
        /// 删除匹配XPath表达式的第一个节点(节点中的子元素同时会被删除)
        /// </summary>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <returns>成功返回true,失败返回false</returns>
        public bool DeleteXmlNodeByXPath(string xpath, string attrName = "", string attrValue = "", bool isSaveXmlDoc = true)
        {
            bool isSuccess = false;
            try
            {
                if (!XmlHasFile())
                    throw new NullReferenceException("Xml Files Is Null");

                var xmlNode = SelectSingleNode(xpath, attrName, attrValue);
                if (xmlNode != null)
                {
                    //删除节点
                    xmlNode.ParentNode?.RemoveChild(xmlNode);
                    if (isSaveXmlDoc)
                        SaveXmlDoc(); //保存到XML文档
                }
                isSuccess = true;
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }

        /// <summary>
        /// 删除匹配XPath表达式的第一个节点中的匹配参数xmlAttributeName的属性
        /// </summary>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <param name="xmlAttributeName">要删除的xmlAttributeName的属性名称</param>
        /// <returns>成功返回true,失败返回false</returns>
        public bool DeleteXmlAttributeByXPath(string xpath, string xmlAttributeName, bool isSaveXmlDoc = true)
        {
            bool isSuccess = false;
            bool isExistsAttribute = false;
            try
            {
                if (!XmlHasFile())
                    throw new NullReferenceException("Xml Files Is Null");

                XmlNode xmlNode = xmlDoc.SelectSingleNode(xpath);
                XmlAttribute xmlAttribute = null;
                if (xmlNode != null)
                {
                    //遍历xpath节点中的所有属性
                    foreach (XmlAttribute attribute in xmlNode.Attributes)
                    {
                        if (attribute.Name.ToLower() == xmlAttributeName.ToLower())
                        {
                            //节点中存在此属性
                            xmlAttribute = attribute;
                            isExistsAttribute = true;
                            break;
                        }
                    }
                    if (isExistsAttribute)
                    {
                        //删除节点中的属性
                        xmlNode.Attributes.Remove(xmlAttribute);
                    }
                }
                if (isSaveXmlDoc)
                    SaveXmlDoc(); //保存到XML文档
                isSuccess = true;
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }

        /// <summary>
        /// 删除匹配XPath表达式的第一个节点中的所有属性
        /// </summary>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <returns>成功返回true,失败返回false</returns>
        public bool DeleteAllXmlAttributeByXPath(string xpath, bool isSaveXmlDoc = true)
        {
            bool isSuccess = false;
            try
            {
                if (!XmlHasFile())
                    throw new NullReferenceException("Xml Files Is Null");

                XmlNode xmlNode = xmlDoc.SelectSingleNode(xpath);
                if (xmlNode != null)
                {
                    //遍历xpath节点中的所有属性
                    xmlNode.Attributes.RemoveAll();
                }
                if (isSaveXmlDoc)
                    SaveXmlDoc(); //保存到XML文档
                isSuccess = true;
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return isSuccess;
        }
        #endregion

        #region 私有方法
        /// <summary>
        /// 判断xml文件是否加载数据。
        /// </summary>
        /// <returns>True为加载，False为未加载数据</returns>
        private bool XmlHasFile()
        {
            return null != this.xmlDoc;
        }

        /// <summary>
        /// 创建一个带有根节点的Xml文件
        /// </summary>
        /// <param name="FileName">Xml文件名称</param>
        /// <param name="RootName">根节点名称</param>
        /// <param name="Encode">编码方式:gb2312，UTF-8等常见的</param>
        /// <param name="DirPath">保存的目录路径</param>
        ///<returns></returns>
        private bool CreatexmlDocument(string FileName, string RootName, string Encode)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(FileName))
                    return false;
                xmlDoc = new XmlDocument();
                XmlDeclaration xmldecl;
                xmldecl = xmlDoc.CreateXmlDeclaration("1.0", Encode, null);
                xmlDoc.AppendChild(xmldecl);
                var xmlelem = xmlDoc.CreateElement("", RootName, "");
                xmlDoc.AppendChild(xmlelem);
                if (!string.IsNullOrWhiteSpace(FileName))
                    xmlDoc.Save(FileName);
                return true;
            }
            catch (Exception e)
            {
                return false;
                throw new Exception(e.Message);
            }
        }
        /// <summary>
        /// 创建一个带有根节点的Xml文件
        /// </summary>
        /// <param name="xmlData">Xml数据</param>
        ///<returns></returns>
        private bool CreatexmlDocument(string xmlData)
        {
            try
            {
                xmlData = ReplaceXmlns(xmlData);
                xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(xmlData);
                return true;
            }
            catch (Exception e)
            {
                //return false;
                throw new Exception(e.Message);
            }
        }

        /// <summary>
        /// 设置节点属性
        /// </summary>
        /// <param name="xe">节点所处的Element</param>
        /// <param name="htAttribute">节点属性，Key代表属性名称，Value代表属性值</param>
        public void SetAttributes(XmlElement xe, IDictionary<string, object> htAttribute)
        {
            foreach (var de in htAttribute)
            {
                if (xe.HasAttribute(de.Key.ToString()) && de.Value.IsNullOrEmpty_())//如果节点有需要更改的属性
                {
                    xe.Attributes.RemoveNamedItem(de.Key.ToString());
                }
                else
                {
                    if (de.Value.IsNotNullOrEmpty_() && !(de.Value is IDictionary<string, object> || de.Value is List<System.Collections.Generic.IDictionary<string, object>>))
                        xe.SetAttribute(de.Key.ToString(), de.Value.ToString());
                }
            }
        }
        /// <summary>
        /// 增加子节点到根节点下
        /// </summary>
        /// <param name="rootNode">上级节点名称</param>
        /// <param name="xmlDoc">Xml文档</param>
        /// <param name="rootXe">父根节点所属的Element</param>
        /// <param name="SubNodes">子节点属性，Key为Name值，Value为InnerText值</param>
        private void SetNodes(string rootNode, XmlDocument xmlDoc, XmlElement rootXe, IDictionary<string, object> SubNodes)
        {
            if (SubNodes == null)
                return;
            foreach (var de in SubNodes)
            {
                //var xmlnode = xmlDoc.SelectSingleNode(rootNode);
                XmlElement subNode = xmlDoc.CreateElement(de.Key.ToString());
                subNode.InnerText = de.Value.ToString();
                rootXe.AppendChild(subNode);
            }
        }
        /// <summary>
        /// 更新节点属性和子节点InnerText值。
        /// </summary>
        /// <param name="root">根节点名字</param>
        /// <param name="htAtt">需要更改的属性名称和值</param>
        /// <param name="htSubNode">需要更改InnerText的子节点名字和值</param>
        private void UpdateNodes(XmlNodeList root, IDictionary<string, object> htAtt, IDictionary<string, object> htSubNode)
        {
            foreach (XmlNode xn in root)
            {
                if (xn.NodeType == XmlNodeType.Comment)
                    continue;
                var xmlelem = (XmlElement)xn;
                if (xmlelem.HasAttributes)//如果节点如属性，则先更改它的属性
                {
                    foreach (var de in htAtt)//遍历属性哈希表
                    {
                        if (xmlelem.HasAttribute(de.Key.ToString()) && !(de.Value is IDictionary<string, object> || de.Value is List<System.Collections.Generic.IDictionary<string, object>>))//如果节点有需要更改的属性
                        {
                            xmlelem.SetAttribute(de.Key.ToString(), de.Value.ToString());//则把哈希表中相应的值Value赋给此属性Key
                        }
                    }
                }
                if (xmlelem.HasChildNodes)//如果有子节点，则修改其子节点的InnerText
                {
                    XmlNodeList xnl = xmlelem.ChildNodes;
                    foreach (XmlNode xn1 in xnl)
                    {
                        XmlElement xe = (XmlElement)xn1;
                        foreach (var de in htSubNode)
                        {
                            if (xe.Name == de.Key.ToString())//htSubNode中的key存储了需要更改的节点名称，
                            {
                                xe.InnerText = de.Value.ToString();//htSubNode中的Value存储了Key节点更新后的数据
                            }
                        }
                    }
                }
            }
        }
        #endregion

        #region XML文档节点查询和读取
        /// <summary>
        /// 根据xpath获取节点
        /// </summary>
        public virtual XmlNode SelectSingleNode(string xpath = "", bool autoCreate = false)
        {
            if (!XmlHasFile())
                throw new NullReferenceException("Xml Files Is Null");

            if (string.IsNullOrWhiteSpace(xpath)) return null;
            else
            {
                var ssnode = xmlDoc.SelectSingleNode(xpath);
                if (ssnode == null && autoCreate)
                {
                    ssnode = CreateNode(xpath);
                }
                return ssnode;
            }
        }
        /// <summary>
        /// 根据xpath获取或创建节点
        /// </summary>
        /// <param name="xpath"></param>
        /// <returns></returns>
        public virtual XmlNode CreateNode(string xpath = "")
        {
            if (!XmlHasFile())
                throw new NullReferenceException("Xml Files Is Null");

            if (string.IsNullOrWhiteSpace(xpath)) return null;
            else
            {
                var ssnode = xmlDoc.SelectSingleNode(xpath);
                if (ssnode == null)
                {
                    var xpaths = xpath.Split('/');
                    var path = "";
                    XmlNode xmlNode = xmlDoc;
                    for (var i = 0; i < xpaths.Length; i++)
                    {
                        path += "/" + xpaths[i].Split('[')[0];
                        var snode = xmlDoc.SelectSingleNode(path.Trim('/'));
                        if (snode == null)
                        {
                            var nnode = xmlDoc.CreateElement(xpaths[i].Split('[')[0]);
                            xmlNode.AppendChild(nnode);
                            xmlNode = nnode;
                        }
                        else
                        {
                            xmlNode = snode;
                        }
                    }
                    ssnode = xmlDoc.SelectSingleNode(xpath);
                }
                return ssnode;
            }
        }
        /// <summary>
        /// 根据xpath获取节点
        /// </summary>
        /// <param name="xpath">xpath</param>
        /// <param name="attrName">属性名</param>
        /// <param name="attrValue">属性值</param>
        /// <returns></returns>
        public virtual XmlNode SelectSingleNode(string xpath, string attrName, string attrValue)
        {
            if (!XmlHasFile())
                throw new NullReferenceException("Xml Files Is Null");
            if (string.IsNullOrWhiteSpace(xpath)) return null;
            else
            {
                if (string.IsNullOrWhiteSpace(attrName))
                    return xmlDoc.SelectSingleNode(xpath);
                else
                    return xmlDoc.SelectSingleNode(xpath + TranslateStr(attrName, attrValue));
            }
        }
        public virtual string TranslateStr(string attrName, string attrValue)
        {
            return "[translate(@" + attrName + ", 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')='" + attrValue.ToLower() + "']";
        }
        public virtual XmlNodeList SelectNodes(string xpath, string attrName, string attrValue)
        {
            if (!XmlHasFile())
                throw new NullReferenceException("Xml Files Is Null");
            if (string.IsNullOrWhiteSpace(xpath)) return null;
            else
            {
                if (string.IsNullOrWhiteSpace(attrName))
                    return xmlDoc.SelectNodes(xpath);
                else
                    return xmlDoc.SelectNodes(xpath + "[translate(@" + attrName + ", 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')='" + attrValue.ToLower() + "']");
            }
        }

        /// <summary>
        /// 选择匹配XPath表达式的第一个节点XmlNode.
        /// </summary>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名")</param>
        /// <returns>返回XmlNode</returns>
        public XmlNode GetXmlNodeByXpath(string xpath)
        {
            try
            {
                XmlNode xmlNode = xmlDoc.SelectSingleNode(xpath);
                return xmlNode;
            }
            catch (Exception ex)
            {
                return null;
                //throw ex; //这里可以定义你自己的异常处理
            }
        }

        /// <summary>
        /// 选择匹配XPath表达式的节点列表XmlNodeList.
        /// </summary>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名")</param>
        /// <returns>返回XmlNodeList</returns>
        public XmlNodeList GetXmlNodeListByXpath(string xpath)
        {
            try
            {
                XmlNodeList xmlNodeList = xmlDoc.SelectNodes(xpath);
                return xmlNodeList;
            }
            catch (Exception ex)
            {
                return null;
                //throw ex; //这里可以定义你自己的异常处理
            }
        }

        /// <summary>
        /// 选择匹配XPath表达式的第一个节点的匹配xmlAttributeName的属性XmlAttribute. /// </summary>
        /// <param name="xpath">要匹配的XPath表达式(例如:"//节点名//子节点名</param>
        /// <param name="xmlAttributeName">要匹配xmlAttributeName的属性名称</param>
        /// <returns>返回xmlAttributeName</returns>
        public XmlAttribute GetXmlAttribute(string xpath, string xmlAttributeName)
        {
            string content = string.Empty;
            XmlAttribute xmlAttribute = null;
            try
            {
                XmlNode xmlNode = xmlDoc.SelectSingleNode(xpath);
                if (xmlNode != null)
                {
                    if (xmlNode.Attributes.Count > 0)
                    {
                        xmlAttribute = xmlNode.Attributes[xmlAttributeName];
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex; //这里可以定义你自己的异常处理
            }
            return xmlAttribute;
        }
        #endregion

        #region static 对象到XML
        /// <summary>
        /// 对象到XML-----泛类型
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="pT">对象</param>
        /// <returns>XML</returns>
        public static string ReplaceXmlns(string xml)
        {
            if (xml == null) return null;
            if (xml.IndexOf("xmlns=", StringComparison.OrdinalIgnoreCase) > 0)
            {
                //xml = System.Text.RegularExpressions.Regex.Replace(xml,
                //@"(xmlns[^=]*=[""][^""]*[""])", "",
                //System.Text.RegularExpressions.RegexOptions.IgnoreCase |
                //System.Text.RegularExpressions.RegexOptions.Multiline);

                xml = System.Text.RegularExpressions.Regex.Replace(xml,
                   @"(xmlns:*[^=]*=[""][^""]*[""])", "",
                   System.Text.RegularExpressions.RegexOptions.IgnoreCase |
                   System.Text.RegularExpressions.RegexOptions.Multiline);

                xml = System.Text.RegularExpressions.Regex.Replace(xml,
                  @"(xsi:*[^=]*=[""][^""]*[""])", "",
                  System.Text.RegularExpressions.RegexOptions.IgnoreCase |
                  System.Text.RegularExpressions.RegexOptions.Multiline);
            }
            return xml;
        }
        public static string T2XML<T>(T pT)
        {
            if (pT == null) return null;
            var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
            MemoryStream stream = new MemoryStream();
            XmlTextWriter xtw = new XmlTextWriter(stream, Encoding.UTF8);
            xtw.Formatting = Formatting.Indented;
            try
            {
                serializer.Serialize(stream, pT);
            }
            catch (Exception ex)
            {
                //LogUtil.Error(ex, "序列化XML失败,类型:" + typeof(T));
                return null;
            }

            stream.Position = 0;
            StringBuilder lbreturnStr = new StringBuilder();
            using (StreamReader sr = new StreamReader(stream, Encoding.UTF8))
            {
                string line = "";
                while ((line = sr.ReadLine()) != null)
                {
                    lbreturnStr.Append(line);
                }
            }
            return lbreturnStr.ToString();
        }
        /// <summary>
        /// 对象到XML-----泛类型
        /// </summary>
        /// <typeparam name="T">泛型对象</typeparam>
        /// <param name="pLT">泛型集合</param>
        /// <returns>XML</returns>
        public static string LT2XML<T>(List<T> pLT)
        {
            if (pLT == null) return null;
            var serializer = new System.Xml.Serialization.XmlSerializer(typeof(List<T>));
            MemoryStream stream = new MemoryStream();
            XmlTextWriter xtw = new XmlTextWriter(stream, Encoding.UTF8);
            xtw.Formatting = Formatting.Indented;
            try
            {
                serializer.Serialize(stream, pLT);
            }
            catch (Exception ex)
            {
                //LogUtil.Error(ex, "序列化XML失败,类型:" + typeof(T));
                return null;
            }

            stream.Position = 0;
            StringBuilder lbreturnStr = new StringBuilder();
            using (StreamReader sr = new StreamReader(stream, Encoding.UTF8))
            {
                string line = "";
                while ((line = sr.ReadLine()) != null)
                {
                    lbreturnStr.Append(line);
                }
            }
            return lbreturnStr.ToString();
        }

        /// <summary>
        /// XML到反序列化到对象----支持泛类型
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="psXML">XML数据</param>
        /// <returns>返回泛型实体</returns>
        public static T XML2T<T>(string psXML)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                using (StreamWriter sw = new StreamWriter(stream, Encoding.UTF8))
                {
                    sw.Write(psXML);
                    sw.Flush();
                    stream.Seek(0, SeekOrigin.Begin);
                    var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
                    try
                    {
                        return ((T)serializer.Deserialize(stream));
                    }
                    catch (Exception ex)
                    { return default(T); }

                }
            }
        }

        /// <summary>
        /// XML到反序列化到对象----支持泛类型
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="psXML">XML数据</param>
        /// <returns>返回泛型实体</returns>
        public static List<T> XML2LT<T>(string psXML)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                using (StreamWriter sw = new StreamWriter(stream, Encoding.UTF8))
                {
                    sw.Write(psXML);
                    sw.Flush();
                    stream.Seek(0, SeekOrigin.Begin);
                    var serializer = new System.Xml.Serialization.XmlSerializer(typeof(List<T>));
                    try
                    {
                        return ((List<T>)serializer.Deserialize(stream));
                    }
                    catch (Exception ex)
                    { return default(List<T>); }

                }
            }
        }
        #endregion
    }
    #endregion
}